﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NGIS.Model;
using NGIS.Data.Schema;

namespace nxmodel.mdl.csharp.test
{
    class Program
    {
        static void test4ModelClass()
        {
            ModelClass modelClass = new ModelClass();

            modelClass.setName("Test Model");
            modelClass.setUID("{B5031C06-2A44-46FA-B359-ABDB19F5198A}");
            modelClass.setExecutionStyle(EExecutionStyle.EES_STATE_SIMULATION);

            //////////////////////////////////////////////////////////////////////////
            //
            // ModelAttribute
            //
            //////////////////////////////////////////////////////////////////////////
            {
                IModelAttribute modelAttribute = modelClass.getModelAttribute();
                ModelCategory modelCategory1;
                modelCategory1.principle = "Machine Learning";
                modelCategory1.path = "DeepLearning/RandomForest";
                modelAttribute.addCategoryInfo(ref modelCategory1);

                LocalAttribute modelLocalAttribute1 = new LocalAttribute();
                modelLocalAttribute1.localType = ELocalizationType.ELT_EN_US;
                modelLocalAttribute1.localName = "RandomForestForIMG";
                modelLocalAttribute1.wikiUrl = "http://en.nnu.edu.cn/";
                modelLocalAttribute1.keywords = new List<string>();
                modelLocalAttribute1.keywords.Add("Random Forest");
                modelLocalAttribute1.keywords.Add("Machine Learning");
                modelLocalAttribute1.abstractInfo = "RandomForest";
                modelAttribute.addLocalAttributeInfo(ref modelLocalAttribute1);

                LocalAttribute modelLocalAttribute2 = new LocalAttribute();
                modelLocalAttribute2.localType = ELocalizationType.ELT_ZH_CN;
                modelLocalAttribute2.localName = "中文名称";
                modelLocalAttribute2.wikiUrl = "http://www.njnu.edu.cn/";
                modelLocalAttribute2.keywords = new List<string>();
                modelLocalAttribute2.keywords.Add("关键字1");
                modelLocalAttribute2.keywords.Add("关键字2");
                modelLocalAttribute2.keywords.Add("关键字3");
                modelLocalAttribute2.abstractInfo = "摘要";
                modelAttribute.addLocalAttributeInfo(ref modelLocalAttribute2);

                //////////////////////////////////////////////////////////////////////////
                modelCategory1.path = "New Path1";
                modelAttribute.updateCategory(0, ref modelCategory1);

                ModelCategory temp_model_cate = new ModelCategory("Principle", "New Path2");
                modelAttribute.updateCategory(0, ref temp_model_cate);
            }

            //////////////////////////////////////////////////////////////////////////
            //
            // ModelBehavior
            //
            //////////////////////////////////////////////////////////////////////////
            {
                IModelBehavior modelBehavior = modelClass.getModelBehavior();
                {
                    ModelDatasetItem modelDatasetItem = new ModelDatasetItem();
                    UdxDatasetSchema dataset1 = new UdxDatasetSchema(null, "Init Parameter");
                    {
                        UdxNodeSchema pNode1 = dataset1.addChildNode("node1", ESchemaNodeType.EDTKT_INT, "int");
                        UdxNodeSchema pNode2 = dataset1.addChildNode("node2", ESchemaNodeType.EDTKT_REAL, "real");
                        UdxNodeSchema pNode3 = dataset1.addChildNode("node3", ESchemaNodeType.EDTKT_LIST);
                        UdxNodeSchema pNode4 = dataset1.addChildNode("node4", ESchemaNodeType.EDTKT_NODE);
                        UdxNodeSchema pNode5 = pNode4.addChildNode("node5", ESchemaNodeType.EDTKT_TABLE, "我也不知道");
                        UdxNodeSchema pNode5_1 = pNode5.addChildNode("node5_1", ESchemaNodeType.EDTKT_INT | ESchemaNodeType.EDTKT_LIST);
                        UdxNodeSchema pNode5_2 = pNode5.addChildNode("node5_2", ESchemaNodeType.EDTKT_REAL | ESchemaNodeType.EDTKT_LIST);
                        UdxNodeSchema pNode5_3 = pNode5.addChildNode("node5_3", ESchemaNodeType.EDTKT_VECTOR2 | ESchemaNodeType.EDTKT_LIST);

                        pNode5_1.getDescription().modifyConceptTag("{941671BD-9ED8-4146-979D-10F7C856DF2A}");
                        pNode5_1.getDescription().modifySpatialReferenceTag("{941671BD-9ED8-4146-979D-10F7C856DF2A}");
                        pNode5_1.getDescription().modifyUnitTag("{941671BD-9ED8-4146-979D-10F7C856DF2A}");
                        pNode5_1.getDescription().modifyDataTemplateTag("{941671BD-9ED8-4146-979D-10F7C856DF2A}");
                    }
                    modelDatasetItem.datasetName = "Related Data1";
                    modelDatasetItem.datasetItemType = EModelDatasetItemType.EMDIT_INTERNAL;
                    modelDatasetItem.datasetItemDescription = "应该是什么描述";
                    modelDatasetItem.externalId = "";
                    modelDatasetItem.datasetItem = dataset1;

                    modelBehavior.addModelDatasetItem(ref modelDatasetItem);

                    //////////////////////////////////////////////////////////////////////////
                    ModelDatasetItem modelDatasetItem1 = new ModelDatasetItem();
                    UdxDatasetSchema dataset2 = new UdxDatasetSchema(null, "Parameter1");
                    {
                        dataset2.addChildNode("Node1", ESchemaNodeType.EDTKT_INT, "Param1");
                        dataset2.addChildNode("Node2", ESchemaNodeType.EDTKT_INT, "Param2");
                        UdxNodeSchema data_node1 = dataset2.addChildNode("Node3", ESchemaNodeType.EDTKT_TABLE, "ParamTable");
                        data_node1.addChildNode("Node3_1", ESchemaNodeType.EDTKT_VECTOR4 | ESchemaNodeType.EDTKT_LIST, "ppp");
                        data_node1.addChildNode("Node3_1", ESchemaNodeType.EDTKT_VECTOR3 | ESchemaNodeType.EDTKT_LIST, "ppp");
                        data_node1.addChildNode("Node3_1", ESchemaNodeType.EDTKT_REAL | ESchemaNodeType.EDTKT_LIST, "ppp");
                    }
                    modelDatasetItem1.datasetName = "Related Data2";
                    modelDatasetItem1.datasetItemType = EModelDatasetItemType.EMDIT_INTERNAL;
                    modelDatasetItem1.datasetItemDescription = "应该是什么描述1";
                    modelDatasetItem1.externalId = "";
                    modelDatasetItem1.datasetItem = dataset2;

                    modelBehavior.addModelDatasetItem(ref modelDatasetItem1);

                    //////////////////////////////////////////////////////////////////////////
                    ModelDatasetItem modelDatasetItem2 = new ModelDatasetItem();
                    modelDatasetItem2.datasetName = "Related Data3";
                    modelDatasetItem2.datasetItemType = EModelDatasetItemType.EMDIT_EXTERNAL;
                    modelDatasetItem2.datasetItemDescription = "应该是什么描述1";
                    modelDatasetItem2.externalId = "{3CC9478F-252E-4631-BA6B-2C5C5CF94E35}";
                    modelDatasetItem2.datasetItem = null;

                    modelBehavior.addModelDatasetItem(ref modelDatasetItem2);
                }// end model dataset

                // begin model state
                {
                    ModelState modelState1 = new ModelState();
                    modelState1.stateId = "{3DCD4B5D-E097-4269-9C0F-6CDE362F33E7}";
                    modelState1.stateName = "Step1";
                    modelState1.stateType = EModelStateType.EMST_BASIC;
                    modelState1.stateDecription = "状态的Description";

                    ModelState modelState2 = new ModelState();
                    modelState2.stateId = "{81D10275-F549-46D3-8741-48EEFEF45F63}";
                    modelState2.stateName = "Step2";
                    modelState2.stateType = EModelStateType.EMST_BASIC;
                    modelState2.stateDecription = "状态的Description";

                    ModelState modelState3 = new ModelState();
                    modelState3.stateId = "{EF1CA40E-A02E-4EB8-A979-2A6C9B36ED54}";
                    modelState3.stateName = "Step3";
                    modelState3.stateType = EModelStateType.EMST_BASIC;
                    modelState3.stateDecription = "状态的Description";

                    //////////////////////////////////////////////////////////////////////////
                    ModelEvent event1 = new ModelEvent();
                    event1.eventName = "Init Event";
                    event1.eventType = EModelEventType.EMET_RESPONSE;
                    event1.eventDescription = "初始化事件";
                    event1.datasetReference = "Related Data1";
                    event1.parameterDescription = "参数描述";
                    modelState1.modelEvents = new List<ModelEvent>();
                    modelState1.modelEvents.Add(event1);

                    //////////////////////////////////////////////////////////////////////////
                    modelBehavior.addModelState(ref modelState1);
                    modelBehavior.addModelState(ref modelState2);
                    modelBehavior.addModelState(ref modelState3);

                    modelBehavior.addModelStateTransition(ref modelState1, ref modelState2);
                    modelBehavior.addModelStateTransition(ref modelState2, ref modelState3);

                    //////////////////////////////////////////////////////////////////////////
                    ModelState temp_state = new ModelState();
                    modelBehavior.getModelState(1, ref temp_state);
                    temp_state.stateName = "New Name";

                    ModelEvent event2 = new ModelEvent();
                    event2.eventName = "Init Event";
                    event2.eventType = EModelEventType.EMET_NORESPONSE;
                    event2.eventDescription = "初始化结束事件";
                    event2.datasetReference = "Related Data2";
                    event2.parameterDescription = "参数描述";
                    temp_state.modelEvents = new List<ModelEvent>();
                    temp_state.modelEvents.Add(event2);

                    modelBehavior.updateModelState(1, ref temp_state);

                    //////////////////////////////////////////////////////////////////////////
                    ModelState temp_state1 = new ModelState();
                    modelBehavior.getModelState(2, ref  temp_state1);

                    ModelEvent event3 = new ModelEvent();
                    event3.eventName = "Load Control Param";
                    event3.eventType = EModelEventType.EMET_CONTROL;
                    event3.eventDescription = "控制参数";
                    event3.parameterDescription = "参数的描述信息";
                    ModelDatasetItem related_data = new ModelDatasetItem();
                    modelBehavior.getModelDatasetItem(2, ref related_data);
                    event3.datasetReference = related_data.datasetName;
                    temp_state1.modelEvents = new List<ModelEvent>();
                    temp_state1.modelEvents.Add(event3);

                    modelBehavior.updateModelState(2, ref temp_state1);
                }// end model state
            }

            //////////////////////////////////////////////////////////////////////////
            //
            // ModelRuntime
            //
            //////////////////////////////////////////////////////////////////////////
            {
                IModelRuntime modelRuntime = modelClass.getModelRuntime();
                modelRuntime.setName("model name");
                modelRuntime.setVersion("5.4");
                modelRuntime.setBaseDirectory("$installPath/taudem/");
                modelRuntime.setEntry("slope.exe");

                HardwareRequirement hardwareRequirement;
                hardwareRequirement.requirementKey = "Main Frequency";
                hardwareRequirement.requirementValue = "2.8";
                modelRuntime.addHardwareRequirement(ref hardwareRequirement);

                SoftwareRequirement softwareRequirement = new SoftwareRequirement();
                softwareRequirement.requirementKey = "Memory Size";
                softwareRequirement.requirementValue = "500M";
                modelRuntime.addSoftwareRequirement(ref softwareRequirement);

                ModelAssembly modelAssembly;
                modelAssembly.assemblyName = "dll";
                modelAssembly.assemblyPath = "./mpi.dll";
                modelRuntime.addModelAssembly(ref modelAssembly);

                SupportiveResource modelSupportiveResource;
                modelSupportiveResource.resourceType = "data";
                modelSupportiveResource.resourceName = "./preload data.txt";
                modelRuntime.addSupportiveResource(ref modelSupportiveResource);
            }


            //! Test Format MDL
            string xml_str = "";
            modelClass.FormatToXmlStream(ref xml_str);

            modelClass.FormatToXmlFile(".\\textmdl.mdl");

            //////////////////////////////////////////////////////////////////////////
            //IModelClass modelClass_load = new ModelClass();
            //modelClass_load.LoadFromXmlStream(xml_str);

            //string xml_str1 = "";
            //modelClass_load.FormatToXmlStream(ref xml_str1);
            //Console.Write(xml_str1);

            //! Test Stardard MDL
            IModelClass pMdl_Demo = new ModelClass();

            pMdl_Demo.LoadFromXmlFile(".\\Demo.mdl");
            pMdl_Demo.FormatToXmlFile(".\\Demo_copy.mdl");

            //! Test Old Version
            IModelClass pMdl_SWMM = new ModelClass();

            pMdl_SWMM.LoadFromXmlFile(".\\Fvcom_lu_step1.mdl");
            pMdl_SWMM.FormatToXmlFile(".\\Fvcom_lu_step1_copy.mdl");

            //////////////////////////////////////////////////////////////////////////
            //{
            //    IModelClass modelClass1 = new ModelClass();
            //    modelClass1.LoadFromXmlFile("AspectAnalysis_FrmDiff.mdl");

            //    IModelClass modelClass2 = new ModelClass();
            //    modelClass2.LoadFromXmlFile("AspectAnalysis_FrmDiff.mdl");

            //    string obj = "";
            //    string name = "";
            //    bool compareFlag = modelClass1.compareOther(modelClass2, true, ref obj, ref name);
            //    Console.Write("\n{0}\n", compareFlag);
            //    Console.Write("{0}\n", obj);
            //    Console.Write("{0}\n", name);

            //}
            //////////////////////////////////////////////////////////////////////////
            Console.ReadKey();
        }

        static void test4MetaData()
        {
            IMetaDataDocument pMetaData = new MetaDataDocument();
            pMetaData.loadFile("E:\\GitCode\\ModelStandardDocuments\\MetaDemo_v4.0.mdle");
            pMetaData.format2File("E:\\GitCode\\ModelStandardDocuments\\MetaDemo_v4.0_t.mdle");
        }

        static void Main(string[] args)
        {
            test4MetaData();
        }
    
    }
}
